package edu.hawaii.duedates;

import java.util.Formatter;
import com.meterware.httpunit.GetMethodWebRequest;
import com.meterware.httpunit.HttpUnitOptions;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebLink;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

/**
 * Due Date Red demonstrates simple use of httpunit to retrieve and parse a web page. Original
 * author by Philip Johnson.
 * 
 * @author Creighton Okada & Ka Hung Phillip Lau
 */
public class DueDates {

  /**
   * Attempts to login to UH Manoa Library system.
   * 
   * @param id The UH user ID.
   * @param lastName The UH user's last name.
   * @return The WebConversation instance after successful login.
   * @throws Exception If login was not successful with these credentials.
   */
  private WebConversation loginToUhLibrary(String id, String lastName) throws Exception {
    String url = "http://uhmanoa.lib.hawaii.edu/cgi-bin/Pwebrecon.cgi?DB=local&PAGE=pbLogon";
    // UH Library Website has bogus JavaScript code.
    HttpUnitOptions.setExceptionsThrownOnScriptError(false);
    // create the conversation object which will maintain state for us
    WebConversation conversation = new WebConversation();
    WebRequest request = new GetMethodWebRequest(url);
    WebResponse response = conversation.getResponse(request);
    WebForm form = response.getFormWithName("logonpage");
    form.setParameter("BC", id);
    form.setParameter("LN", lastName);
    form.submit();
    response = conversation.getCurrentPage();
    if (response.getText().contains(
        "Sorry, Login unsuccessful.  Username and/or password" + " is not correct")) {
      throw new Exception("Error while logging in to UH Library");
    }
    return conversation;
  }

  /**
   * Attempts to login to the Hawaii State Library System.
   * 
   * @param id The hawaii library id barcode.
   * @param password The password (last four digits of your phone number).
   * @return The WebConversation after logging in.
   * @throws Exception If errors occur while logging in.
   */
  private WebConversation loginToHawaiiStateLibrary(String id, String password) throws Exception {
    try {
      String url = "http://www.librarieshawaii.org/";
      // Website has bogus JavaScript code.
      HttpUnitOptions.setExceptionsThrownOnScriptError(false);
      // create the conversation object which will maintain state for us
      WebConversation conversation = new WebConversation();
      WebRequest request = new GetMethodWebRequest(url);
      WebResponse response = conversation.getResponse(request);
      WebLink link = response.getLinkWith("My Account");
      link.click();
      response = conversation.getCurrentPage();
      WebForm form = response.getForms()[0];
      form.setParameter("sec1", id);
      form.setParameter("sec2", password);
      form.submit();
      return conversation;
    }
    catch (Exception e) {
      throw new Exception("Error while logging in to Hawaii State Library", e);
    }
  }

  /**
   * Given a logged in user to the UH Library site, provides info about their library books.
   * 
   * @param id The UH user ID.
   * @param lastName The UH user's last name.
   * @return A String containing information about their books.
   * @throws Exception If problems occur parsing the site pages.
   */
  public String getUhInfo(String id, String lastName) throws Exception {
    String uhSiteNoItemString = "You have no items checked out.";
    String bookResults = null;
    try {
      WebConversation conversation = this.loginToUhLibrary(id, lastName);
      WebResponse response = conversation.getCurrentPage();
      WebForm form = response.getForms()[0];
      if (uhSiteNoItemString.equals(form.getText())) {
        return "No items checked out";
      }
      else {

        WebTable table = response.getTables()[0];

        if (table.getText().contains("Block Reason")) {
          try {
            WebTable table2 = response.getTables()[1];

            if ((table2.getText().contains("Checked Out: Due"))) {
              for (int a = 0; a < table2.getRowCount(); a++) {
                bookResults = table2.getCellAsText(a, 3) + " -- " + table2.getCellAsText(a, 1)
                    + "\n\n";
              }
              return bookResults;
            }
          }
          catch (Exception e) {
            System.out.println("No items checked out");
          }
        }
        else if (table.getText().contains("Checked Out: Due")) {
          for (int c = 0; c < table.getRowCount(); c++) {
            bookResults = table.getCellAsText(c, 3) + " -- " + table.getCellAsText(c, 1) + "\n\n";
          }
          return bookResults;
        }
      }
    }
    catch (Exception e) {
      throw new Exception("Error getting UH Book info", e);
    }
    return uhSiteNoItemString;
  }

  /**
   * Gets info from the Hawaii State Library site.
   * 
   * @param hiStateId The barcode number from the library card.
   * @param hiStatePassword The password (normally the last four digits of your phone number).
   * @return A string providing information about checked out books.
   * @throws Exception If problems occur getting the information.
   */
  public String getHawaiiStateInfo(String hiStateId, String hiStatePassword) throws Exception {
    try {
      WebConversation conversation = this.loginToHawaiiStateLibrary(hiStateId, hiStatePassword);
      WebResponse response = conversation.getCurrentPage();
      WebLink link = response.getLinkWith("Items Out");
      link.click();
      response = conversation.getCurrentPage();
      StringBuilder outputString = new StringBuilder();
      Formatter formatter = new Formatter(outputString);
      boolean noBooksOut = response.getText().contains("Checked Out: 0");
      if (!noBooksOut) {
        WebTable table = response.getTableStartingWith("Title");
        int rowCount = table.getRowCount();
        int columnCount = table.getColumnCount();
        int counter = 0;
        String content[] = new String[rowCount * columnCount];
        for (int i = 0; i < rowCount; i++) {
          for (int j = 0; j < columnCount; j++) {
            content[counter] = table.getCellAsText(i, j).replace("\n", "");
            counter++;
          }
        }
        for (int i = 0; i < content.length; i += 3) {
          formatter
              .format("|%-70.70s\t|%-10s|%-10s|\n", content[i], content[i + 1], content[i + 2]);
        }
      }
      return (noBooksOut) ? "No items checked out" : "\n" + outputString;
    }
    catch (Exception e) {
      throw new Exception("Error getting Hawaii State Library info", e);
    }
  }

  /**
   * The main class illustrates the use of this code to login in systems.
   * 
   * @param params Four strings: uhID, uhLastName, hiStateId, hiStatePassword.
   * @throws Exception If problems occur accessing the library sites.
   */
  public static void main(String[] params) throws Exception {
    DueDates dueDate = new DueDates();

    try {
      if (params[0].equals("-uhm")) {
        // Check UH Manoa Library
        String uhId = params[1];
        String uhLastName = params[2];
        System.out.printf("Getting data from UH Manoa%n");
        String uhInfo = dueDate.getUhInfo(uhId, uhLastName);
        System.out.printf("Results for UH Manoa:%n %s%n", uhInfo);
      }

      else if (params[0].equals("-hsl")) {
        // Check the Hawaii State Library.
        String hiStateId = params[1];
        String hiStatePassword = params[2];
        System.out.printf("Getting data from Hawaii State Library System "
            + "(this can take 1 minute)%n");
        String hiInfo = dueDate.getHawaiiStateInfo(hiStateId, hiStatePassword);
        System.out.printf("\nResults for Hawaii State Library:%n %s%n", hiInfo);
      }

      else {
        // incorrect param argument
        System.out.println("Incorrect library name.  Choose -hsl for Hawaii State"
            + "Library or -uhm for University of Hawaii Library.");
      }
    }
    catch (Exception IndexOutOfBounds) {
      System.out.println("Invalid parameters entered.  Check if first parameter is a valid" +
          " library and that login parameters are valid.");
    }

  }
}
